#include "DashboardUI.h"
#include "ui_dashboard.h"

#include "Authentication.h"

#include "DashboardUI_AddPrescription.h"
#include "DashboardUI_AddRecord.h"
#include "DashboardUI_EditUser.h"
#include "DashboardUI_PatientAdd.h"
#include "DashboardUI_PatientSelect.h"
#include "DashboardUI_ViewGraph.h"
#include "DashboardUI_ViewPrescriptions.h"
#include "DashboardUI_ViewRecords.h"

#include "UIManager.h"

#include <qmessagebox.h>

Dashboard::Dashboard(UIManager *manager, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Dashboard)
{
    ui->setupUi(this);
    this->manager = manager;

    patientSelectPanel = nullptr;

	// If -debug option, set up debug menu
	QCoreApplication * app = QApplication::instance();
	if (app->arguments().indexOf("-debugMode") >= 0)
	{
		QMenu * debugMenu = ui->menubar->addMenu("Debug");
		QAction * randAction = debugMenu->addAction("Create random records");

		connect(randAction, SIGNAL(triggered()), this, SLOT(debug_random_records()));
	}

    setupTabs();
}

void Dashboard::setupTabs()
{
    User *user = Authentication::getInstance()->getUser();

    // Set up tabs based on user type
    switch (user->getUserType())
    {
        case User::ADMIN:
            addTab(new DashboardUI_EditUser(), "Create User");
            windowTitle = "Admin Dashboard";
            break;

        case User::DOCTOR:
            addRecordTabs();
            addTab(new DashboardUI_ViewGraph(), "View Graphs", true);
            addPrescriptionTabs();
            addPatientPanel();
            windowTitle = "Doctor Dashboard";
            break;

        case User::PATIENT:
            addRecordTabs();
            addTab(new DashboardUI_ViewGraph(), "View Graphs");
            addTab(new DashboardUI_EditUser(), "View Information");
            addTab(new DashboardUI_ViewPrescriptions(), "View Prescriptions", true);
            windowTitle = "Patient Dashboard";
            break;

        case User::NURSE:
            addRecordTabs();
            addTab(new DashboardUI_ViewGraph(), "View Graphs", true);
            addTab(new DashboardUI_EditUser(), "Create Patient");
            addPatientPanel();
            windowTitle = "Nurse Dashboard";
            break;

        default:
            addRecordTabs();
    }

    setWindowTitle(windowTitle);
}

void Dashboard::addTab(QWidget *tab, QString tabTitle, bool reload, bool changesData)
{
    ui->tabWidget->addTab(tab, tabTitle);

    if (reload)
        connect(this, SIGNAL(reloaded()), tab, SLOT(reload()));

    if (changesData)
        connect(tab, SIGNAL(dataChanged()), this, SLOT(reload()));
}

void Dashboard::addRecordTabs()
{
    // Create record add and view widgets
    DashboardUI_AddRecord * add = new DashboardUI_AddRecord();
    DashboardUI_ViewRecords * view = new DashboardUI_ViewRecords();

    // When a record is added, update the viewing widget
    connect(add, SIGNAL(recordsChanged()), view, SLOT(reload()));

    // Add widgets to dashboard tabs
    addTab(add, "Add Record", true);
    addTab(view, "View All Records", true);
}

void Dashboard::addPatientPanel()
{
    // Create patient selection panel
    patientSelectPanel = new DashboardUI_PatientSelect();

    // When the user selects a patient, reload dashboard
    connect(patientSelectPanel, SIGNAL(userChanged()), this, SLOT(reload()));

    ui->splitter->insertWidget(0, patientSelectPanel);

    // Add patient add option to menu
    ui->menuFile->insertAction(ui->actionLogout, new QAction("Add Patient", ui->menuFile));
    ui->menuFile->insertSeparator(ui->actionLogout);

    connect(ui->menuFile->actions().at(0), SIGNAL(triggered()),
            this, SLOT(on_actionAdd_Patient_triggered()));
}

void Dashboard::addPrescriptionTabs()
{
    // Create prescription adding and viewing widgets
    DashboardUI_AddPrescription * add = new DashboardUI_AddPrescription();
    DashboardUI_ViewPrescriptions * view = new DashboardUI_ViewPrescriptions();

    // If a prescription is added, update prescription list widget
    connect(add, SIGNAL(prescriptionsChanged()), view, SLOT(reload()));

    // Add widgets to dashboard tab widget
    addTab(add, "Enter Prescription");
    addTab(view, "View Prescriptions");
}

void Dashboard::closeEvent(QCloseEvent *evt) 
{
    hide();
    manager->showLogin();
}

Dashboard::~Dashboard()
{
    delete ui;
}

void Dashboard::on_actionLogout_triggered()
{
    hide();
    manager->showLogin();
}

void Dashboard::on_actionAdd_Patient_triggered()
{
    // Create new patient add widget
    DashboardUI_PatientAdd *addPatient = new DashboardUI_PatientAdd();

    // When a patient is added, update the patient list panel
    connect(addPatient, SIGNAL(patientAdded()), patientSelectPanel, SLOT(reload()));

    // Show the patient add widget in a new window
    addPatient->show();
}

void Dashboard::debug_random_records()
{
	Authentication * auth = Authentication::getInstance();
	User * user = auth->getUser();

	int userId = -1;

	// Find current patient
	if (user->getUserType() == User::PATIENT)
		userId = user->getId();
	else
	{
		User * patient = auth->getPatient();

		if (patient == nullptr)
		{
			QMessageBox::warning(this, "Error", "No user currently selected");
			return;
		}
		else
			userId = patient->getId();
	}

	// Generate random records
	RecordDatabase recordDB;
	recordDB.generateRandomRecords(userId, 50);

	QMessageBox::information(this, "Notice", "Records created");
	emit reloaded();
}

void Dashboard::reload()
{
    User * selectedPatient = Authentication::getInstance()->getPatient();

    // If a patient is selected, update the window title to show
    // the patient's name
    if (selectedPatient != nullptr)
    {
        PersonInfo * info = selectedPatient->getInfo();
        setWindowTitle(windowTitle + " - Viewing patient: " +
                       info->firstName + " " + info->lastName);
    }
    else
        setWindowTitle(windowTitle);

    // Trigger reloaded event so that tabs that need to update can update
    emit reloaded();
}

